package com.hccl.service.parser;

import DM.DialogManager;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hccl.exception.updateException;
import com.hccl.mongoEntities.*;
import com.hccl.service.classifier.MaxEntClassifier;
import com.hccl.service.gate.GateMatcher;
import com.hccl.service.similarity.SimilarityUtil;
import com.hccl.util.FileOperations;
import entities.Param;
import entities.SLUResult;
import entities.StateNode;
import entities.SysAction;
import gate.Annotation;
import gate.Factory;
import gate.Gate;
import gate.Resource;
import gate.creole.ExecutionException;
import gate.creole.ResourceInstantiationException;
import gate.util.GateException;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.query.Query;

import java.io.*;
import java.util.*;

import static com.hccl.config.Constants.*;
import static com.hccl.config.Constants.gateGazetteerPath;

/**
 * Created by sunjia on 2018/4/21.
 * 处理理解流程
 */
public class Parser {

    ArrayList<SLUResult> currentSLU;
    SysAction currentAction = null;
    Set<Annotation> currentGaz = new HashSet<>();
    int id;

    private PreprocessUtil preprocesser = new PreprocessUtil();
    private SimilarityUtil similarityUtil = new SimilarityUtil();
    private MaxEntClassifier classifier = new MaxEntClassifier();
    private DialogManager dialogManager;
    private GateMatcher gateMatcher;
    private Datastore datastore;

    public Parser(DialogManager dialogManager, Integer i, Datastore datastore) throws Exception {
        List<GrammarVariableEntity> entities = datastore.createQuery(GrammarVariableEntity.class).asList();
        this.gateMatcher = new GateMatcher(entities);
        this.dialogManager = dialogManager;
        this.id = i;
        this.datastore = datastore;
    }

    public SysAction keypadParser(String keypad,
                                  String userid,
                                  String telephoneNumber,
                                  Map<String,String> newAddParam)
            throws Exception {

        try {
            GateAnalyseResultEntity gateResult = gateMatcher.gateAnalyse(keypad);
            currentSLU = gateResult.getSluResults();
            currentAction = parseAction(gateResult.getConflictReply(), userid, keypad, telephoneNumber, newAddParam);
            currentGaz = gateResult.getCurrentGaz();
        } catch (ResourceInstantiationException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return currentAction;
    }

    public SysAction queryParser(String input,
                                 String userid,
                                 String telephoneNumber,
                                 Map<String,String> newAddParam)
            throws Exception {
        try {
            if (StringUtils.isEmpty(input)||input.trim().equals("")) {
                currentSLU = new ArrayList<SLUResult>();
                currentAction = parseAction("", userid, input, telephoneNumber, newAddParam);
                return currentAction;
            }
            //step1 预处理：替换掉荷包这类情况
            String inputPrepro = preprocesser.preprocess(input);
            //step2 Gate 解析slot
            GateAnalyseResultEntity gateResult = gateMatcher.gateAnalyse(inputPrepro);
            currentGaz = gateResult.getCurrentGaz();
            for (SLUResult sluResult : gateResult.getSluResults()){//若走语法时Gate有非##结果,则不走统计方法
                if (sluResult.ruleName.trim().length()>0 && !sluResult.ruleName.equals("##")){
                    currentSLU = gateResult.getSluResults();
                    currentAction = parseAction("", userid, input, telephoneNumber, newAddParam);
                    return currentAction;
                }
            }
            if (getClassifierDate()){//有语料
                //step3 获取分类标签，通过两种方式：1 相似度计算（编辑距离）； 2分类器
                ArrayList<SLUResult> combineResults;
                ArrayList<SLUResult> similarityResult = similarityUtil.compute(inputPrepro);
                if (similarityResult.size() > 0) {//得到匹配结果，和Gate相结合
                    combineResults = combineResult(similarityResult, gateResult.getSluResults());
                    currentSLU = combineResults;
                } else { //编辑距离没有结果，进入分类器
                    ArrayList<SLUResult> classifierResults = classifier.predict(inputPrepro);//获取分类器结果
                    if (classifierResults.size() > 0) { //分类器有结果，则合并
                        combineResults = combineResult(classifierResults, gateResult.getSluResults());
                        currentSLU = combineResults;
                    } else {//若没有分类器结果，直接采用gate结果
                        currentSLU = gateResult.getSluResults();
                    }
                }
            }else{
                currentSLU = gateResult.getSluResults();
            }
            currentAction = parseAction(gateResult.getConflictReply(), userid, input, telephoneNumber, newAddParam);
        }catch (ResourceInstantiationException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return currentAction;
    }

    public SysAction greeting(String userid, String tel, Map<String,String> newAddParam){

        currentAction = dialogManager.getFirstQusetion(userid, tel, newAddParam);
        return currentAction;
    }

    public boolean getClassifierDate() throws IOException {
        boolean flag = false;
        StringBuffer sb= new StringBuffer("");
        BufferedReader br = new BufferedReader(new FileReader(classifierTraindataPath));
        String str = "";
        while((str = br.readLine()) != null) {
            sb.append(str+"/n");
            if (sb.length()>10){
                flag = true;
                break;
            }
        }
        return flag;
    }


    //组合：编辑距离/分类器和Gate的结果。两个SLUResult的组合。
    public ArrayList<SLUResult> combineResult(ArrayList<SLUResult> Results,
                                              ArrayList<SLUResult> gateResult) {

        ArrayList<SLUResult> combineResults = new ArrayList<>();
        for (SLUResult result: Results){
            if (gateResult.size() > 0) {
                combineResults.add(new SLUResult(result.ruleName, result.ruleType, result.score, gateResult.get(0).slots));
            }else {//若Gate未找到slot
                combineResults.add(new SLUResult(result.ruleName, result.ruleType, result.score, new HashMap<>()));
            }
        }
        return combineResults;

    }

    //接收Gate标注结果+userid送入对话管理器
    public SysAction parseAction(String conflictReply,
                                 String userid,
                                 String input,
                                 String telephoneNumber,
                                 Map<String, String> newAddParam){

        ArrayList<SLUResult> res = new ArrayList<>();
        res.addAll(currentSLU);
        String note = "";//input正常，as正常，无note
        if (input.trim().equals("")){
            note = "noInput";

        }else if (res == null || res.size() == 0){
            note = "noMatch";
        }
        SysAction ac = null;
        try {
            ac = dialogManager.feedUserInput(userid, res, note,conflictReply, telephoneNumber, newAddParam);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (note.equals("") && ac == null) {
                System.out.println("对话管理器失败！ ");
            }
        }
        return ac;
    }

    public ArrayList<SLUResult> getCurrentSLU() {
        return currentSLU;
    }

    public SysAction getCurrentAction() {
        return currentAction;
    }

    public Set<Annotation> getCurrentGaz() {
        return currentGaz;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    /*============================================UPDATE START=======================================*/
    public void parserUpdate() throws updateException {
        try {
            updateGateGrammar();                                        // 1 更新本地语法文件
            cleanupSerialController();
            Gate.init();
            createJsonfromDB(nodeInfoPath);                             // 2 更新Json
            DB2Corpus();                                                // 3 更新语料
            similarityUtil.updateSimilarityMap();                       // 4 更新similarity中的dictionaryMap
            classifier.updateModel();                                   // 5 更新分类器model
        }catch (Exception e){
            throw new updateException("更新时parserUpdate()出错。系统尝试自动恢复...");
        }
    }


    public void cleanupSerialController() {//删除GateMatcher gateMatcher参数

        for(Object aPr :new ArrayList(gateMatcher.getAnalyser().getPRs())){
            Factory.deleteResource((Resource)aPr);
        }
        Factory.deleteResource(gateMatcher.getAnalyser());
    }

    /*=============================UPDATE FILE OF JAPE & GAZETTEER =============================*/


    public void updateGateGrammar() throws updateException {
        DB2Jape();
        DB2Gazetteer();
    }

    private void DB2Jape() throws updateException {
        OutputStreamWriter fw = null;
        try{
            FileOperations.delete(gateJapePath);
            File file = new File(gateJapePath);
            file.mkdir();
            fw = new OutputStreamWriter(new FileOutputStream(gateJapePath + "main.jape", false),"UTF-8");
            fw.write("MultiPhase: TestTheGrammars\nPhases:\n");
            Query<NavigationEntity> queryNavi = datastore.createQuery(NavigationEntity.class);
            for(NavigationEntity navi : queryNavi) {
                for (GrammarRuleEntity rule : navi.getRules()) {
                    String strRule = "rule_" + rule.getId();
                    fw.write(strRule + "\n");
                    //开始写每一条Rule
                    OutputStreamWriter fwRule =
                            new OutputStreamWriter(new FileOutputStream(gateJapePath + strRule + ".jape", false), "UTF-8");
                    fwRule.write("Phase: " + strRule + "\nInput: ");
                    //Input时注意判断语义槽还是变量,并用List存放变量
                    List<RuleEntryEntity> entries = rule.getLists();
                    List<RuleEntryEntity> entries_vari = new ArrayList<RuleEntryEntity>();
                    for (RuleEntryEntity entry : entries) {
                        String entryName = entry.getName();
                        String finalEntryName = entryName;
                        if (entry.getType() == 1) {
                            entries_vari.add(entry);//用于之后的循环
                            String entryNameTmp = entryName.replace("$","");
                            GrammarVariableEntity vari = datastore.createQuery(GrammarVariableEntity.class)
                                    .field("name").equal(entryNameTmp).get();
                            if (vari.getType().contains(".")) {
                                finalEntryName = vari.getType().split("\\.")[0];
                            } else {
                                finalEntryName = vari.getType();
                            }
                        }
                        fwRule.write("\"" + finalEntryName + "\"" + " ");
                    }
                    fwRule.write("\nOptions: control = brill debug = true\n");
                    fwRule.write("\nRule: " + strRule + "\n(\n");
                    fwRule.write(makeEntry_All(rule.getLists(), rule.getOrdered()) + "\n");
                    System.out.println(makeEntry_All(rule.getLists(), rule.getOrdered()));
                    fwRule.write(")\n:" + strRule + "\n-->\n" + "{\n");
                    Formatter fmt = new Formatter();
                    fmt.format("\tAnnotationSet as= (gate.AnnotationSet)bindings.get(\"%s\");\n"
                                    + "\tFeatureMap features=Factory.newFeatureMap();\n"
                                    + "\tdouble effectiveLength=0;\n"
                                    + "\tint distance=0;\n"
                                    + "\tfor(Annotation i : as){\n"
                                    + "\t\tString matchedString=doc.getContent().toString().substring(\n"
                                    + "\t\t\ti.getStartNode().getOffset().intValue(), i.getEndNode().getOffset().intValue());\n"
                                    + "\t\tfeatures.put(\"MatchedToken:\"+matchedString, i.getFeatures().get(\"matchedString\")+\":\"+i.getType());\n"
                                    + "\t\tlong matchedLength=(long)matchedString.length();\n"
                                    + "\t\tdistance+=(int)i.getFeatures().get(\"distance\");\n"
                                    + "\t\teffectiveLength+=(double)matchedLength;\n\t}\n\n"
                                    + "\tFeatureMap featuresSlots=Factory.newFeatureMap();\n\n",
                            strRule);
                    //一条语法有几个变量要循环几次
                    for (RuleEntryEntity entry : entries_vari) {
                        String variName = "vari_" + entry.getEntry().toString();
                        fmt.format("\tAnnotationSet as_%s= (gate.AnnotationSet)bindings.get(\"%s\");\n"
                                        + "\tif(as_%s != null && as_%s.size() != 0){\n"
                                        + "\t\tFeatureMap featuresGet = as_%s.iterator().next().getFeatures();\n"
                                        + "\t\tfeaturesSlots.put(\"%s\", featuresGet);\n\t}\n\n",
                                variName, variName, variName, variName, variName, entry.getName());
                    }
                    fmt.format("\tfeatures.put(\"effective_length\", effectiveLength-distance);\n"
                                    + "\tfeatures.put(\"rule\", \"%s\");\n"
                                    + "\tfeatures.put(\"type\", \"stateNode\");\n"
                                    + "\tfeatures.put(\"slotNum\", as.size());\n"
                                    + "\tfeatures.put(\"slots\", featuresSlots);\n",
                            navi.getId());
                    if (rule.isVaribleRule()) {
                        fmt.format("\tdouble inputLen = (double)doc.getContent().toString().length();\n"
                                + "\tif(inputLen*0.4<effectiveLength)\n"
                                + "\t\toutputAS.add(as.firstNode(), as.lastNode(), \"command\", features);\n}\n\n");
                    } else {
                        fmt.format("\toutputAS.add(as.firstNode(), as.lastNode(), \"command\", features);\n}\n\n");
                    }
                    fwRule.write(fmt.toString());
                    fwRule.close();
                }
                //command
                Query<CommandEntity> q_command = datastore.createQuery(CommandEntity.class);
                for(CommandEntity command : q_command){
                    for (GrammarRuleEntity rule : command.getRules()){
                        String strCommand = "command_" + rule.getId();
                        fw.write(strCommand + "\n");
                        OutputStreamWriter fwCommand =
                                new OutputStreamWriter(new FileOutputStream(gateJapePath + strCommand + ".jape", false),"UTF-8");
                        fwCommand.write("Phase: "+ strCommand + "\nInput: ");
                        Set<String> entrySet2 = new HashSet<String>();
                        List<RuleEntryEntity> entries2 = rule.getLists();
                        for(RuleEntryEntity entry : entries2){
                            String entryName = entry.getName();
                            entrySet2.add(entryName);
                        }
                        for(String name : entrySet2){
                            fwCommand.write("\"" + name + "\"" + " ");
                        }
                        fwCommand.write("\nOptions: control = brill debug = true\n");
                        fwCommand.write("\nRule: " + strCommand + "\n(\n");
                        fwCommand.write(makeEntry_All(rule.getLists(),command.isOrdered()) + "\n");
                        fwCommand.write(")\n:" + strCommand + "\n-->\n" + "{\n");
                        Formatter fmt = new Formatter();
                        fmt.format("\tAnnotationSet as= (gate.AnnotationSet)bindings.get(\"%s\");\n"
                                        +"\tFeatureMap features=Factory.newFeatureMap();\n"
                                        +"\tdouble effectiveLength=0;\n"
                                        +"\tint distance=0;\n"
                                        +"\tfor(Annotation i : as){\n"
                                        +"\t\tString matchedString=doc.getContent().toString().substring(\n"
                                        +"\t\t\ti.getStartNode().getOffset().intValue(), i.getEndNode().getOffset().intValue());\n"
                                        +"\t\tfeatures.put(\"MatchedToken:\"+matchedString, i.getFeatures().get(\"matchedString\")+\":\"+i.getType());\n"
                                        +"\t\tlong matchedLength=(long)matchedString.length();\n"
                                        +"\t\tdistance+=(int)i.getFeatures().get(\"distance\");\n"
                                        +"\t\teffectiveLength+=(double)matchedLength;\n\t}\n\n"
                                        +"\tFeatureMap featuresSlots=Factory.newFeatureMap();\n\n"
                                        +"\tfeatures.put(\"effective_length\", effectiveLength-distance);\n"
                                        +"\tfeatures.put(\"rule\", \"%s\");\n"
                                        +"\tfeatures.put(\"type\", \"command\");\n"
                                        +"\tfeatures.put(\"slotNum\", as.size());\n"
                                        +"\tfeatures.put(\"slots\", featuresSlots);\n"
                                        +"\toutputAS.add(as.firstNode(), as.lastNode(), \"command\", features);\n}\n\n",
                                strCommand,command.getName());
                        fwCommand.write(fmt.toString());
                        fwCommand.close();
                    }
                }
            }
            fw.close();
        }catch (Exception e){
            throw new updateException("更新时生成Jape文件出错。系统尝试自动恢复...");
        }
    }

    private String makeEntry_All(List<RuleEntryEntity> entries, boolean order){

        String str = "";
        String strdis = "";//可选
        Map<String, String> entriesAllMap= new LinkedHashMap<>();//用于有序语法
        Map<String, String> varOrderMap=new HashMap<>();//用于存储同一类型的变量
        Set<String> quchongVOM=new HashSet<>();
        List<String> entriesdis = new ArrayList<String>();
        List<String> entriesindis = new ArrayList<String>();//必选
        for (RuleEntryEntity entry : entries){
            String entryName = entry.getName();
            String line = "";
            if (entry.getType() == 1) {//变量
                String entryNameTmp = entryName.replace("$","");
                GrammarVariableEntity vari = datastore.createQuery(GrammarVariableEntity.class)
                        .field("name").equal(entryNameTmp).get();
                //判断下type的格式是否正确，不正确直接跳出。
                String variType = vari.getType();
                if (variType.contains(".") && variType.contains("==")) {
                    String variTypeFormate = "\"" + variType.split("\\.")[0] + "\"" + ".\""
                            + variType.split("\\.")[1].split("==")[0] + "\"==\""
                            + variType.split("\\.")[1].split("==")[1] + "\"";
                    line = "({" +  variTypeFormate + "})" + ":" + "vari_" + entry.getEntry() + " ";
                } else {
                    line = "({\"" +  variType + "\"})" + ":" + "vari_" + entry.getEntry() + " ";
                }
                if (entry.isDispensable()){ //可选的格式在下面处理
                    entriesdis.add(line);
                    entriesAllMap.put(line, "dis");
                }else {
                    entriesindis.add(line);
                    entriesAllMap.put(line, "indis");//必选
                    if(!quchongVOM.contains(entry.getEntry())){
                        if(varOrderMap.containsKey(variType)){
                            String temp=varOrderMap.get(variType);
                            temp=temp+"#"+line;
                            varOrderMap.put(variType,temp);
                        }else {
                            varOrderMap.put(variType,line);
                        }
                        quchongVOM.add(entry.getEntry());
                    }
                }
            }else {//语义槽
                line = "{\"" + entryName +"\"}";
                if (entry.isDispensable()) { //可选的格式在下面处理
                    entriesdis.add(line);
                    entriesAllMap.put(line, "dis");
                } else {//必选
                    entriesindis.add("(" + line + ") ");
                    entriesAllMap.put("(" + line + ") ", "indis");
                }
            }
        }
        //去重
        entriesdis = filterSLots(entriesdis);
        entriesindis = filterSLots(entriesindis);
        if(entriesdis.size()>0){//可选的entry大于0
            strdis = "(" + JoinStr(entriesdis," | ") + ")* ";
        }
        List<String> res = new ArrayList<String>();
        if (order) {//有序，只需要罗列出res就行
            str = getOrderRule(entriesAllMap);
        }else{
            allRange(entriesindis, 0, entriesindis.size()-1, res, strdis,varOrderMap);
            str = JoinStr(res, "|\n");
        }
        return str;
    }

    private static List<String> filterSLots(List<String> slots){
        Set<String> slotSet = new HashSet<String>();
        for (String str:slots){
            slotSet.add(str);
        }
        List<String> newSet = new ArrayList<String>();
        for (String str:slotSet){
            newSet.add(str);
        }
        return newSet;
    }

    private static String getOrderRule(Map<String, String> entriesAllMap){

        String str = "";
        for(Map.Entry<String, String> entry : entriesAllMap.entrySet() ){
            String line = entry.getKey();
            String isdis = entry.getValue();
            if (isdis.equals("dis")){//可选
                line = "(" + entry.getKey() + ")* ";
            }
            str += line;
        }
        return str;
    }

    //获取所有排列组合
    private static void allRange(List<String> entries, int n, int m, List<String> res, String str2,Map<String,String> varOrderMap){
        if(n==m){
            boolean flag=true;
            if(varOrderMap.size()>0){
                for (Map.Entry<String, String> entry : varOrderMap.entrySet()) {
                    if(!flag)break;
                    String temp=entry.getValue();
                    if(temp.contains("#")){
                        String[] order=temp.split("#");
                        List<String> temlist=new ArrayList<>();
                        for(int i=0;i<order.length;i++)temlist.add(order[i]);
                        flag = containAndOrdered(entries,temlist);
                    }
                }
            }
            if(flag)res.add("\t(" + str2 + JoinStr(entries,str2) + str2 + ")");
        } else {
            for (int i=n;i<=m;i++){
                String tmp = entries.get(n);
                entries.set(n, entries.get(i));
                entries.set(i, tmp);
                allRange(entries, n+1, m, res, str2,varOrderMap);
                tmp = entries.get(n);
                entries.set(n, entries.get(i));
                entries.set(i, tmp);
            }
        }
    }

    private static boolean containAndOrdered(List<String> l1,List<String> l2){
        boolean res=false;
        int p1=0,p2=0;
        while (p1<l1.size()&&p2<l2.size()){
            if(l1.get(p1).equals(l2.get(p2))){
                p2++;
            }
            p1++;
        }
        if(p2==l2.size())res=true;
        return res;
    }

    private static String JoinStr(List<String> strlist, String sep){
        String str = "";
        for (String string : strlist){
            str += string;
            str += sep;
        }
        if(strlist.size()>0){
            str = str.substring(0, str.length()-sep.length());
        }
        return str;
    }

    /*==============================ABOVE=JAPE; BELOW=GAZETTEER=========================*/

    private  void DB2Gazetteer() throws updateException {

        List<GrammarSlotEntity> list_s = datastore.createQuery(GrammarSlotEntity.class).asList();
        OutputStreamWriter fw = null;
        try{
            FileOperations.delete(gateGazetteerPath);
            File file = new File(gateGazetteerPath);
            file.mkdir();
            fw =new OutputStreamWriter(new FileOutputStream(gateGazetteerPath + "list.def",false),"UTF-8");
            for(GrammarSlotEntity slot : list_s){
                if(!slot.getLists().isEmpty()){
                    String slotName = slot.getId();
                    fw.write(slotName + ".lst::::" + slotName + "\n");
                    OutputStreamWriter fwSlot =
                            new OutputStreamWriter(new FileOutputStream(gateGazetteerPath + slotName + ".lst", false),"UTF-8");
                    for (String entry : slot.getLists()){
                        fwSlot.write(entry+"\n");
                    }
                    fwSlot.close();
                }
            }
            Query<GrammarElementEntity> queryElement = datastore.createQuery(GrammarElementEntity.class);
            for(GrammarElementEntity element : queryElement){
                if (element != null) {
                    String eleName = element.getName();
                    fw.write(eleName + ".lst::::" + eleName + "\n");
                    OutputStreamWriter fwEle =
                            new OutputStreamWriter(new FileOutputStream(gateGazetteerPath + eleName + ".lst", false), "UTF-8");
                    List<EmbedElementEntity> embedLs = element.getElelists();
                    for (EmbedElementEntity embed : embedLs) {
                        List<String> userInputLs = embed.getUserinput();
                        String standardName = embed.getStandardName();
                        Map<String, String> attMap = embed.getAttlists();
                        String attString = "";
                        if (attMap != null ) {
                            for (Map.Entry<String, String> entry : attMap.entrySet()) {
                                String pair = entry.getKey() + "=" + entry.getValue();
                                attString += pair + "&";
                            }
                            for (String userInput : userInputLs) {
                                String line = userInput + "&" + "抽取名=" + standardName + "&" + attString.substring(0, attString.length() - 1);
                                fwEle.write(line + "\n");
                            }
                        } else {
                            for (String userInput : userInputLs) {
                                String line = userInput + "&" + "抽取名=" + standardName;
                                fwEle.write(line + "\n");
                            }
                        }
                    }
                    fwEle.close();
                }
            }
            fw.close();
        } catch (Exception e){
            throw new updateException("更新时生成Gazetteer文件出错。系统尝试自动恢复...");
        }
    }

    /*================================JSON-UPDATE==========================================*/

    public void createJsonfromDB(String path) throws updateException{
        try {
            //先删掉原始文件
//        FileOperations.delete(nodeInfoPath);
            //写节点
            Query<NavigationEntity> q = datastore.createQuery(NavigationEntity.class).field("_id").equal("root");
            NavigationEntity root = q.get();
            System.out.println(root != null);
            if (root != null) {
                //设置节点(用递归的方法设置节点)
                setChildNavigationEntity(root);
            }
            writeJsonStringToFile(path + "stateNode.json", root);

            //写processes
            Query<ProcessEntity> processes = datastore.createQuery(ProcessEntity.class);
            FileOperations.delete(path + "processes//");
            File file = new File(path + "processes//");
            file.mkdir();
            for (ProcessEntity p : processes) {
                writeJsonStringToFile(path + "processes//" + p.getName() + ".json", p);
            }

            //写api
            List<APIsEntity> apiArrayList = new ArrayList<APIsEntity>();
            Query<APIsEntity> apilists = datastore.createQuery(APIsEntity.class);
            for (APIsEntity p : apilists) {
                apiArrayList.add(p);
                writeJsonStringToFile(path + "apilist.json", apiArrayList);
            }

            //写config
            Query<ConfigEntity> configQuery = datastore.createQuery(ConfigEntity.class);
            ConfigEntity config = configQuery.get();
            writeJsonStringToFile(path + "config.json", config);

//        //写params
            List<GrammarVariableEntity> paramsList = new ArrayList<GrammarVariableEntity>();
            Query<GrammarVariableEntity> paramsQuery = datastore.createQuery(GrammarVariableEntity.class);
            for (GrammarVariableEntity param :
                    paramsQuery) {
                paramsList.add(param);
            }
            writeJsonStringToFile(path + "params.json", paramsList);
        }catch (Exception e){
            throw new updateException("更新时生成nodeInfo文件出错。系统尝试自动恢复...");
        }
    }
    private void writeJsonStringToFile(String path,Object object)throws IOException{
        ObjectMapper mapper = new ObjectMapper();
        String jsonString = mapper.writeValueAsString(object);
        OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(path,false),"UTF-8");
        fw.write(jsonString);
        //System.out.println(jsonString);
        fw.close();
    }

    private void setChildNavigationEntity(NavigationEntity root){
        root.setCorpus(null);
        List<NavigationEntity> children  = root.getSubStateNode();
        if (children.size()==0){
            return;
        }
        for (int i = 0; i <children.size() ; i++) {
            String name = children.get(i).getId();
            Query<NavigationEntity> q = datastore.createQuery(NavigationEntity.class).field("_id").equal(name);
            System.out.println(name);
            NavigationEntity child = q.get();
            root.getSubStateNode().set(i,child);
            setChildNavigationEntity(child);
        }

    }
    /*=================================CORPUS-UPDATE=========================================*/

    public void DB2Corpus() throws updateException {

        try {
            //清空文件
            FileOperations.delete(corpusPath);
            File file = new File(corpusPath);
            file.mkdir();

            //nodeCorpus
            Query<NavigationEntity> queryNavi = datastore.createQuery(NavigationEntity.class);
            for (NavigationEntity navi : queryNavi) {
//            获取到节点的语料并且存到resources/Corpus
                if (!navi.getId().contains("##") && !navi.getId().contains("root")) {
                    List<String> corpus_node = navi.getCorpus();
                    OutputStreamWriter fw_navi = new OutputStreamWriter(new FileOutputStream
                            (corpusPath + "stateNode@" + navi.getId(), false), "UTF-8");
                    for (String c : corpus_node) {
                        //用于编辑距离计算的文本需要去标点去空格
                        c = c.replaceAll("[\\pP\\p{Punct}]", "").replace(" ", "");
                        fw_navi.write(c + "\n");
                    }
                    fw_navi.close();
                }
            }

            //commandCorpus
            Query<CommandEntity> queryCommand = datastore.createQuery(CommandEntity.class);
            for (CommandEntity comm : queryCommand) {
//            获取到节点的语料并且存到resources/Corpus
                List<String> corpus_comm = comm.getCorpus();
                OutputStreamWriter fw_comm = new OutputStreamWriter(new FileOutputStream
                        (corpusPath + "command@" + comm.getName(), false), "UTF-8");
                for (String c : corpus_comm) {
                    c = c.replaceAll("[\\pP\\p{Punct}]", "").replace(" ", "");
                    fw_comm.write(c + "\n");
                }
                fw_comm.close();
            }
        }catch (Exception e){
            throw new updateException("更新时生成courpus文件出错。系统尝试自动恢复...");
        }
    }
   /*=================================UPDATE END=========================================*/

}
